﻿// Copyright 2007-2009 Stuart Caborn, Alex Scordellis
//  
//  Licensed under the Apache License, Version 2.0 (the "License"); you may not
//  use this file except in compliance with the License. You may obtain a copy of
//  the License at
//  
//  http://www.apache.org/licenses/LICENSE-2.0
//  
//  Unless required by applicable law or agreed to in writing, software
//  distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
//  WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
//  License for the specific language governing permissions and limitations under
//  the License.
// 


using System.Linq;
using NUnit.Framework;
using NUnit.Framework.SyntaxHelpers;
using Rhino.Mocks;
using SampleApp.Monitored;

namespace NSynthesis.Test.Wired
{
    [TestFixture]
    public class MethodRecorderTest_IncidentalImplementations
    {
        [SetUp]
        public void SetUp()
        {
            Synthesis.Reset();
            mocks = new MockRepository();
        }

        private MockRepository mocks;

        [Test]
        public void nsynthesis_should_detect_monitored_incedental_implementations()
        {
            //See NSynthesis.Test\Reflection\IncidentalImplementationOfAnInterface.cd  
            var mockRepository = mocks.CreateMock<IRepository>();
            mockRepository.Exists(3);
            Assert.That(Synthesis.Recorder.MockedMethodCalls.Count(), Is.EqualTo(1));
            Assert.That(Synthesis.Recorder.MockedMethodCalls.First().RealImplementations.Count(), Is.EqualTo(1));
        }

        [Test]
        public void if_an_interface_is_implemented_by_a_superclass_nsyntheis_should_detect_it_being_called()
        {
            IRepository realRepository = new Repository();
            Assert.That(realRepository is BaseRepository);
            realRepository.Exists(3);
            Assert.That(Synthesis.Recorder.RealMethodCalls.Count(), Is.EqualTo(1));

            realRepository.Exists(1);
        }

        [Test]
        public void if_an_interface_is_implemented_by_a_superclass_testing_the_base_class_counts()
        {
            //See NSynthesis.Test\Reflection\IncidentalImplementationOfAnInterface.cd  
            var mockRepository = mocks.CreateMock<IRepository>();
            mockRepository.Exists(3);
            Assert.That(Synthesis.Recorder.MockedMethodCalls.Count(), Is.EqualTo(1));
            Assert.That(Synthesis.Recorder.MockedMethodCalls.First().IsNotResolved);

            IRepository realRepository = new Repository();
            Assert.That(realRepository is BaseRepository);
            realRepository.Exists(3);
            Assert.That(Synthesis.Recorder.MockedMethodCalls.First().IsNotResolved, Is.False);

            realRepository.Exists(1);
        }

        [Test]
        public void if_an_interface_is_implemented_by_a_superclass_the_untested_base_class_is_correctly_reported()
        {
            //See NSynthesis.Test\Reflection\IncidentalImplementationOfAnInterface.cd  
            var mockRepository = mocks.CreateMock<IRepository>();
            mockRepository.Exists(3);

            var report = new Report(Synthesis.Recorder.MissingMethods, Synthesis.Recorder.MockedMethodCalls, Synthesis.Recorder.RealMethodCalls);
            Assert.That(report.Errors.Count, Is.EqualTo(1));
            Assert.That(report.Errors[0].MockedMethod, Is.EqualTo("bool SampleApp.Monitored.IRepository::Exists(int)"));
            Assert.That(report.Errors[0].MissingMethod, Is.EqualTo("bool SampleApp.Monitored.Repository::Exists(int)"));
        }
    }
}